import worker from '@ohos.worker';
import { MessageExchange, operation, protocol, SocketExchange, type } from './WorkerExchange'
import { Address, BasicNetworkUtil, Type } from '../common/NetWork/BasicNetworkUtil';
import { TcpUtils } from '../common/network/NetworkImpl/TcpUtils';
import { FlightGearDecoder } from '../common/NetWork/DecodeImpl/FlightGearDecode';
import { UdpUtils } from '../common/NetWork/NetworkImpl/UdpUtils';

const workerPort = worker.workerPort;

let socketContainer = new Map<Address, any>();

workerPort.onmessage = (event) => {
  let data = event.data;
  let object = SocketExchange.fromObject(data);

  if (object) {
    if (object.operation == operation.create) {
      if (object.protocol == protocol.tcp) {
        if (object.type == type.remote) {
          let address = new Address();
          address.ip = object.ip;
          address.port = object.port;
          let tcpUtils = new TcpUtils(new FlightGearDecoder(), Type.remote, address);
          socketContainer.set(address, tcpUtils);
        } else {
          let address = new Address();
          address.ip = object.ip;
          address.port = object.port;
          let tcpUtils = new TcpUtils(new FlightGearDecoder(), Type.local, address);
          socketContainer.set(address, tcpUtils);
          tcpUtils.recv((data) => {
            workerPort.postMessage(data);
          });
        }
      } else if (object.protocol == protocol.udp) {
        if (object.type == type.remote) {
          let address = new Address();
          address.ip = object.ip;
          address.port = object.port;
          let udpUtils: BasicNetworkUtil = new UdpUtils(new FlightGearDecoder(), Type.remote, address, true);
          socketContainer.set(object, udpUtils);
        } else if (object.type == type.local) {
          let address = new Address();
          address.ip = object.ip;
          address.port = object.port;
          let udpUtils: BasicNetworkUtil = new UdpUtils(new FlightGearDecoder(), Type.local, address, false);
          socketContainer.set(object, udpUtils);
          setTimeout(() => {
            udpUtils.recv((data) => {
              workerPort.postMessage(data);
            });
          }, 100);
        }
      }
    } else if (object.operation == operation.close) {
      let address = new Address();
      address.ip = object.ip;
      address.port = object.port;
      socketContainer.get(address).close();
      socketContainer.delete(address);
    }
  }

  let msg = MessageExchange.fromObject(data);
  if (msg) {
    let address = new Address();
    address.ip = msg.ip;
    address.port = msg.port;
    socketContainer.get(address).send(msg.message);
  }


}